#pragma once

#include <thread>
#include <future>

BEGIN_ARETE_NAMESPACE(thread)

struct AEPackageBase
{
	virtual void execute() = 0;
};

template <class T>
struct AEPackage : public AEPackageBase
{
	AEPackage(std::packaged_task<T()> &&_t) : m_task(std::move(_t)) { }

	void execute()
	{
		m_task();
	}

	std::packaged_task<T()> m_task;
};

class AETask
{
public:
	template<class T>
	AETask(std::packaged_task<T()> &&_task) : m_ptr(new AEPackage<T>(std::move(_task))) { }
	~AETask(void);

	void operator()();

private:
	std::shared_ptr<AEPackageBase> m_ptr;
};

END_ARETE_NAMESPACE